package com.yourenbang.lingyun.transaction.web.controller.manage;

import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.WithDrawStatusEnum;
import com.yourenbang.lingyun.constants.enums.fund.AccountType;
import com.yourenbang.lingyun.constants.enums.table.PayTransactionEnum;
import com.yourenbang.lingyun.core.base.controller.BaseController;
import com.yourenbang.lingyun.core.base.interceptor.ExcludeInterceptor;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.model.vo.PageVO;
import com.yourenbang.lingyun.core.util.ExportExcelUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.transaction.web.domain.dto.manage.TradeManageDTO;
import com.yourenbang.lingyun.transaction.web.service.manage.ManageService;
import com.yourenbang.lingyun.transaction.web.service.manage.ManageTradeService;
import com.yourenbang.transaction.api.model.dto.manage.QueryClientFirstPageStatisticsDTO;
import com.yourenbang.transaction.api.model.dto.manage.QueryClientPledgeListDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * Created on 2021/11/11
 *
 * @author qinmingtao
 * desc 基梯后台交易相关接口
 */
@Slf4j
@RestController
@RequestMapping("/transaction/manage/client")
public class ManageClientController extends BaseController {
    private static final String KEY_NAME="name";
    private static final String VALUE_NAME="value";

    @Autowired
    private ManageTradeService manageTradeService;
    @Autowired
    ManageService manageService;

    /**
     * 交易明细的选项列表
     */
    @ExcludeInterceptor
    @PostMapping("/trade/choose/list")
    Result chooseList() {
        JSONObject jResults = new JSONObject();
        //产品类型
        List<JSONObject> productType = new ArrayList<>();
        JSONObject productTypeItem1 = new JSONObject();
        productTypeItem1.put(KEY_NAME, "电签");
        productTypeItem1.put(VALUE_NAME, 1);
        productType.add(productTypeItem1);
        JSONObject productTypeItem2 = new JSONObject();
        productTypeItem2.put(KEY_NAME, "大pos");
        productTypeItem2.put(VALUE_NAME, 2);
        productType.add(productTypeItem2);
        jResults.put("productType", productType);

        //交易状态
        List<JSONObject> tradeStatus = new ArrayList<>();
        JSONObject tradeStatusItem0 = new JSONObject();
        tradeStatusItem0.put(KEY_NAME, "交易成功");
        tradeStatusItem0.put(VALUE_NAME, PayTransactionEnum.TransactionStatus.STATUS_10.getCode());
        tradeStatus.add(tradeStatusItem0);
        JSONObject tradeStatusItem1 = new JSONObject();
        tradeStatusItem1.put(KEY_NAME, "交易失败");
        tradeStatusItem1.put(VALUE_NAME, PayTransactionEnum.TransactionStatus.STATUS_20.getCode());
        tradeStatus.add(tradeStatusItem1);
        jResults.put("tradeStatus", tradeStatus);

        //交易类型
        List<JSONObject> cardFlag = new ArrayList<>();
        JSONObject cardFlagItem0 = new JSONObject();
        cardFlagItem0.put(KEY_NAME, "贷记卡");
        cardFlagItem0.put(VALUE_NAME, PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode());
        cardFlag.add(cardFlagItem0);
        JSONObject cardFlagItem1 = new JSONObject();
        cardFlagItem1.put(KEY_NAME, "借记卡");
        cardFlagItem1.put(VALUE_NAME, PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode());
        cardFlag.add(cardFlagItem1);
        JSONObject cardFlagItem2 = new JSONObject();
        cardFlagItem2.put(KEY_NAME, "扫码");
        cardFlagItem2.put(VALUE_NAME, "CODE");
        cardFlag.add(cardFlagItem2);
        JSONObject cardFlagItem3 = new JSONObject();
        cardFlagItem3.put(KEY_NAME, "银联二维码贷记");
        cardFlagItem3.put(VALUE_NAME, PayTransactionEnum.CardFlagEnum.UNIONCODE_CREDIT.getCode());
        cardFlag.add(cardFlagItem3);
        JSONObject cardFlagItem4 = new JSONObject();
        cardFlagItem4.put(KEY_NAME, "银联二维码借记");
        cardFlagItem4.put(VALUE_NAME, PayTransactionEnum.CardFlagEnum.UNIONCODE_DEBIT.getCode());
        cardFlag.add(cardFlagItem4);
        jResults.put("cardFlag", cardFlag);

        return Result.builder().success(jResults);
    }

    /**
     * 基梯后台交易明细
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13179">火眼api</a>
     */
    @ExcludeInterceptor
    @PostMapping(value = "/trade/list")
    public Result tradeList(@Validated @RequestBody TradeManageDTO dto, BindingResult br) {
        KLog.info("[基梯后台交易明细]入参:{}", dto.toString());
        if(StringUtils.isEmpty(dto.getClientNo())){
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "基梯参数异常");
        }
        dto.setPlatNo(PlatNoEnums.YXY.getCode());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        return manageTradeService.clientTradeList(dto);
    }

    @ExcludeInterceptor
    @GetMapping(value = "/export/trade/list")
    public void exportTradeList(TradeManageDTO dto, HttpServletRequest request, HttpServletResponse response) {
        KLog.info("[基梯后台交易明细导出]入参:{}", dto.toString());
        if (StringUtils.isEmpty(dto.getClientNo())) {
            KLog.warn("[基梯后台交易列表导出]基梯参数异常");
            return;
        }
        dto.setPlatNo(PlatNoEnums.YXY.getCode());
        dto.setPageSize(0);
        Result result = manageTradeService.clientTradeList(dto);
        if (!result.isSuccess()) {
            KLog.warn("[基梯后台交易明细导出]{}", result.getDesc());
        } else {
            String title = "交易明细导出-" + DateFormat.DATETIME_COMPACT.format(LocalDateTime.now());
            String[] headers = {"交易订单号", "商户姓名", "商户手机号", "商户号", "交易金额", "费率", "产品类型", "交易状态", "交易类型", "交易时间", "机具号"};
            String[] fieldNames = {"orderNo", "name", "phone", "merchantNo", "transactionAmount", "rate","productType","statusName", "cardFlagName", "transactionTime", "terminalSn"};
            ExportExcelUtils.exportExcel(title, headers, fieldNames, ((PageVO) result.getData()).getList(), request, response);
        }
    }

    /**
     * 基梯后台交易统计
     * @param dto 搜索参数
     * @return com.yourenbang.lingyun.transaction.web.domain.vo.manage.ManageClientTransactionStatisticsVO
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13548">火眼api</a>
     */
    @ExcludeInterceptor
    @PostMapping(value = "/trade/statistics")
    public Result tradeStatistics(@Validated @RequestBody TradeManageDTO dto, BindingResult br) {
        KLog.info("[基梯后台交易统计]入参:{}", dto.toString());
        if(StringUtils.isEmpty(dto.getClientNo())){
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "基梯参数异常");
        }
        dto.setPlatNo(PlatNoEnums.YXY.getCode());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        return manageTradeService.clientTradeStatistics(dto);
    }
    /**
     * 押金对账列表
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13182">火眼api</a>
     * @param dto 查询条件
     * @return 押金列表
     */
    @ExcludeInterceptor
    @PostMapping(value = "/pledge/list")
    public Result pledgeList(@Validated @RequestBody QueryClientPledgeListDTO dto, BindingResult br) {
        KLog.info("[基梯后台押金对账列表]入参:{}", dto.toString());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        dto.setAgentIds(ManageTradeService.JT_AGENT_IDS);
        return manageTradeService.queryClientPledgeList(dto);
    }

    /**
     * 押金对账列表 导出
     */
    @ExcludeInterceptor
    @GetMapping(value = "/export/pledge/list")
    public void exportPledgeList(QueryClientPledgeListDTO dto, HttpServletRequest request, HttpServletResponse response) {
        KLog.info("[基梯后台押金对账列表导出]入参:{}", dto.toString());
        dto.setPageSize(0);
        dto.setAgentIds(ManageTradeService.JT_AGENT_IDS);
        Result result = manageTradeService.queryClientPledgeList(dto);
        if (!result.isSuccess()) {
            KLog.warn("[基梯后台押金对账列表导出]{}", result.getDesc());
        } else {
            String title = "押金对账导出-" + DateFormat.DATETIME_COMPACT.format(LocalDateTime.now());
            String[] headers = {"商户姓名", "商户手机号", "商户号", "机具类型", "机具号", "押金金额", "缴纳时间"};
            String[] fieldNames = {"merchantName", "phone", "merchantNo", "productType", "terminalSn", "payAmount","payTime"};
            ExportExcelUtils.exportExcel(title, headers, fieldNames, ((PageVO) result.getData()).getList(), request, response);
        }
    }

    /**
     * 押金对账列表 （旧机构）
     */
    @ExcludeInterceptor
    @PostMapping(value = "/pledge/list/old")
    public Result pledgeListOld(@Validated @RequestBody QueryClientPledgeListDTO dto, BindingResult br) {
        KLog.info("[基梯后台押金对账列表旧]入参:{}", dto.toString());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        dto.setAgentIds(ManageTradeService.YXY_AGENT_IDS);
        return manageTradeService.queryClientPledgeList(dto);
    }

    /**
     * 押金对账列表导出 （旧机构）
     */
    @ExcludeInterceptor
    @GetMapping(value = "/export/pledge/list/old")
    public void exportPledgeListOld(QueryClientPledgeListDTO dto, HttpServletRequest request, HttpServletResponse response) {
        KLog.info("[基梯后台押金对账列表导出旧]入参:{}", dto.toString());
        dto.setPageSize(0);
        dto.setAgentIds(ManageTradeService.YXY_AGENT_IDS);
        Result result = manageTradeService.queryClientPledgeList(dto);
        if (!result.isSuccess()) {
            KLog.warn("[基梯后台押金对账列表导出旧]{}", result.getDesc());
        } else {
            String title = "押金对账导出-" + DateFormat.DATETIME_COMPACT.format(LocalDateTime.now());
            String[] headers = {"商户姓名", "商户手机号", "商户号", "机具类型", "机具号", "押金金额", "缴纳时间"};
            String[] fieldNames = {"merchantName", "phone", "merchantNo", "productType", "terminalSn", "payAmount","payTime"};
            ExportExcelUtils.exportExcel(title, headers, fieldNames, ((PageVO) result.getData()).getList(), request, response);
        }
    }

    /**
     * 押金统计
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13185">火眼api</a>
     * @param dto 查询条件
     * @return 押金统计结果
     */
    @ExcludeInterceptor
    @PostMapping(value = "/pledge/statistics")
    public Result pledgeStatistics(@Validated @RequestBody QueryClientPledgeListDTO dto, BindingResult br) {
        KLog.info("[基梯后台押金统计结果]入参:{}", dto.toString());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        dto.setAgentIds(ManageTradeService.JT_AGENT_IDS);
        return manageTradeService.queryClientPledgeStatistics(dto);
    }

    /**
     * 押金统计 旧机构
     * @param dto
     * @param br
     * @return
     */
    @ExcludeInterceptor
    @PostMapping(value = "/pledge/statistics/old")
    public Result pledgeStatisticsOld(@Validated @RequestBody QueryClientPledgeListDTO dto, BindingResult br) {
        KLog.info("[基梯后台押金统计结果]入参:{}", dto.toString());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        dto.setAgentIds(ManageTradeService.YXY_AGENT_IDS);
        return manageTradeService.queryClientPledgeStatistics(dto);
    }

    /**
     * 基梯后台首页统计
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13191">火眼api</a>
     * @param dto 查询条件
     * @return 统计结果
     */
    @ExcludeInterceptor
    @PostMapping(value = "/first/page/statistics")
    public Result firstPageStatistics(@Validated @RequestBody QueryClientFirstPageStatisticsDTO dto, BindingResult br) {
        KLog.info("[基梯首页统计结果]入参:{}", dto.toString());
        Result verifyParam = verifyParam(br);
        if (!verifyParam.isSuccess()) {
            return verifyParam;
        }
        return manageTradeService.queryClientFirstPageStatistics(dto);
    }

    /**
     * 提现记录页面的筛选条件
     * @see <a href="https://huoyan.kaolakuaishou.cn/project/97/interface/api/13362">火眼api</a>
     */
    @ExcludeInterceptor
    @GetMapping("/withdraw/record/choose/list")
    Result withdrawRecordChooseList() {
        JSONObject jResults = new JSONObject();
        //账户类型
        List<JSONObject> accountType = new ArrayList<>();
        JSONObject accountTypeItem1 = new JSONObject();
        accountTypeItem1.put(KEY_NAME, "服务费账户");
        accountTypeItem1.put(VALUE_NAME, AccountType.ALLY.getShortAccountNo());
        accountType.add(accountTypeItem1);
        JSONObject productTypeItem2 = new JSONObject();
        productTypeItem2.put(KEY_NAME, "分润账户");
        productTypeItem2.put(VALUE_NAME, AccountType.ALLY_PROFIT.getShortAccountNo());
        accountType.add(productTypeItem2);
        jResults.put("accountType", accountType);

        //提现状态
        List<JSONObject> withdrawStatus = new ArrayList<>();
        JSONObject withdrawStatusItem0 = new JSONObject();
        withdrawStatusItem0.put(KEY_NAME, "审核中");
        withdrawStatusItem0.put(VALUE_NAME, WithDrawStatusEnum.WITHDRAW_STATUS_WAIT.getCode());
        withdrawStatus.add(withdrawStatusItem0);
        JSONObject withdrawStatusItem1 = new JSONObject();
        withdrawStatusItem1.put(KEY_NAME, "提现成功");
        withdrawStatusItem1.put(VALUE_NAME, WithDrawStatusEnum.WITHDRAW_STATUS_SUCCESS.getCode());
        withdrawStatus.add(withdrawStatusItem1);
        JSONObject withdrawStatusItem2 = new JSONObject();
        withdrawStatusItem2.put(KEY_NAME, "提现失败");
        withdrawStatusItem2.put(VALUE_NAME, WithDrawStatusEnum.WITHDRAW_STATUS_FAIL.getCode());
        withdrawStatus.add(withdrawStatusItem2);
        jResults.put("withdrawStatus", withdrawStatus);

        return Result.builder().success(jResults);
    }

}
